package com.handl.springcloud.common.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * Created by handl on 2017/10/30.
 *
 * 实现自己的路由过滤功能
 * 1.继承zuul的ZuulFilter类
 * 2.重写4个方法
 *      filterType():过滤器的类型，决定着过滤器在请求的哪个生命周期中执行
 *              这里定义为‘pre’，代表着请求在路由之前执行
 *      filterOrder()：代表着过滤器执行的顺序，当在同一个生命周期阶段有多个过滤器时
 *              按照此方法的返回值来决定并依次执行
 *      shouldFilter()：代表着过滤器是否会执行，这里直接返回true代表着所有的请求都会执行，
 *              实际生产中，可以通过此方法来确定过滤器执行的范围。
 *      run()：过滤器的具体逻辑，
 *              ctx.setSendZuulResponse(false);代表不对请求进行路由
                ctx.setResponseStatusCode(401);设置返回的状态码
 */
//声明为一个spring组件并被扫描，不然过滤器不起作用
@Component
public class SimpleZuulFilter extends ZuulFilter {
    /**
     * pre:在请求被路由之前调用
     * routing:在路由请求时被调用
     * error:处理请求时发生错误时被调用
     * post:在routhing和error过滤器之后被调用
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 值越小越优先执行
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 控制过滤器是否执行
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 真正的过滤器逻辑
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        String token = request.getParameter("token");

        if (null == token){
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            try {
                ctx.getResponse().setCharacterEncoding("GBK");
                ctx.getResponse().getWriter().write("路由过滤错误！！！");
            } catch (IOException e) {}
        }
        return null;
    }
}
